package ioAdmin;

//#####################################################################
/*
 * TITULO: Clase Expresion regular
 * AUTORES: Mora Rodriguez Carolina
 * MATERIA: Compiladores
 * GRUPO: 3CM6
 * PROFESOR: Juarez Gambino Joel Omar
 */
//#####################################################################

//********************************************************************
//BIBLIOTECAS
//********************************************************************
import java.util.*;
import java.io.*;

//#####################################################################
//CLASE
//#####################################################################
/*
 * DESCRIPCION: 
 */
public class ExpresionRegular {

	// ********************************************************************
	// PARAMETROS
	// ********************************************************************
	private String cadena = new String();

	// ----------------- SETS ------------------------------
	void set_cadena(String cad) {
		cadena = cad;
	}

	// ----------------- GETS ------------------------------
	public String get_cadena() {
		return new String(cadena);
	}

	// ********************************************************************
	// CONSTRUCTOR
	// ********************************************************************
	public ExpresionRegular(String cad) {
		cadena = cad;
	}

	// ********************************************************************
	// PRUEBA DE FUNCIONAMIENTO
	// ********************************************************************
	public static void main(String args[]) {
		String expresion = "";

		System.out.print("Introduzca la expresion regular: ");
		try {
			BufferedReader entrada = new BufferedReader(new InputStreamReader(
					System.in));
			expresion = entrada.readLine();
		} catch (IOException e) {
		}

		ExpresionRegular er = new ExpresionRegular(expresion);
		ArrayList<Character> posfija = er.InfijoAPosfijo();
		System.out.println(posfija.toString());
		ArrayList<Character> alfabeto = er.ObtenerAlfabeto();
		System.out.println(alfabeto.toString());

	}

	// ********************************************************************
	// METODOS
	// ********************************************************************

	/*---------------- FUNCION INFIJA A POSFIJA ------------
	 * ENTRADA:
	 * SALIDA:
	 * FUNCIONAMIENTO:
	 */
	public ArrayList<Character> InfijoAPosfijo() {
		System.out.println("cadena inicial" + cadena);
		char[] array = this.cadena.toCharArray();
		Stack<Character> pila = new Stack<Character>();
		ArrayList<Character> lista = new ArrayList<Character>();

		for (int i = 0; i < array.length; i++) {
			if (array[i] == '(')
				pila.push('(');
			else if (Character.isLetterOrDigit(array[i]))
				lista.add(array[i]);
			else if (array[i] == ')') {
				while (!pila.empty()) {
					if (pila.peek() == '(') {
						pila.pop();
						break;
					}
					lista.add(pila.peek());
					pila.pop();
				}
			} else {
				if (pila.empty())
					pila.push(array[i]);
				else if (pila.peek() == '(')
					pila.push(array[i]);
				else {
					char aux = array[i];
					while (pila.peek() == '*' | pila.peek() == '+'
							| pila.peek() == '|' | pila.peek() == '-') {
						if (MayorIgualPresedencia(pila.peek(), aux)) {
							lista.add(pila.peek());
							pila.pop();
							pila.push(aux);
						} else
							break;
						aux = pila.pop();
						if (pila.empty())
							break;
					}
					pila.push(aux);
				}
			}
		}
		while (!pila.empty()) {
			lista.add(pila.peek());
			pila.pop();
		}
		for(Character lis:lista)
			System.out.println(lis);
		return lista;
	}

	/*---------------- FUNCION MAYOR PRESEDENCIA ------------
	 * ENTRADA:
	 * SALIDA:
	 * FUNCIONAMIENTO:
	 */
	public static boolean MayorIgualPresedencia(char ope1, char ope2) {
		if (ope1 == '*' | ope1 == '+')
			return true;
		else if (ope1 == '-') {
			if (ope2 == '*' | ope2 == '+')
				return false;
			else
				return true;
		} else
			return false;
	}

	/*---------------- FUNCION OBTENER ALFABETO ------------
	 * ENTRADA:
	 * SALIDA:
	 * FUNCIONAMIENTO:
	 */
	public ArrayList<Character> ObtenerAlfabeto() {
		char[] array = this.cadena.toCharArray();
		
		ArrayList<Character> alfabeto = new ArrayList<Character>();

		for (int i = 0; i < array.length; i++) {
			if (Character.isLetterOrDigit(array[i])) {
				if (!alfabeto.contains(array[i]))
					alfabeto.add(array[i]);
			}
		}
		return alfabeto;
	}

}